package modelo.bd.dao;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;
import modelo.bd.ConexionPool;
import modelo.bd.excepcion.DAOException;
import modelo.dominio.Flujo;

public class FlujoDAO {

    private String query;

    public void add(Flujo entity, String usuario) throws DAOException {
        Connection conexion = null;
        PreparedStatement sentencia = null;
        try {
            query = "INSERT INTO sil_flujos (fluj_clave,"
                    + "                fluj_descripcion,"
                    + "                fluj_desc_corta,"
                    + "                fluj_valida_monto,"
                    + "                fluj_comentarios,"
                    + "                fluj_estatus,"
                    + "                fluj_usuario_creo,"
                    + "                fluj_fecha_creo) "
                    + "VALUES('" + entity.getClave()
                    + "','" + entity.getDescripcion()
                    + "','" + entity.getDescripcionCorta()
                    + "','" + (entity.isValidaMonto() ? "S" : "N")
                    + "','" + entity.getComentarios()
                    + "','" + entity.getEstatus() + "',"
                    + "'" + usuario
                    + "', SYSDATE)";
            conexion = ConexionPool.getInstancia().getConexion();
            sentencia = conexion.prepareStatement(query);
            sentencia.executeUpdate();
        } catch (SQLException ex) {
            throw new DAOException("Error FLDA-SQL " + ex.getMessage());
        } finally {
            try {
                if (sentencia != null) {
                    sentencia.close();
                }
                if (conexion != null) {
                    conexion.close();
                }
            } catch (SQLException ex) {
                throw new DAOException("Error FLDA-SQL " + ex.getMessage());
            }
        }
    }

    public void update(Flujo entity, String usuario) throws DAOException {
        Connection conexion = null;
        PreparedStatement sentencia = null;
        try {
            query = "UPDATE sil_flujos \n"
                    + "SET    fluj_descripcion   = '" + entity.getDescripcion() + "', \n"
                    + "       fluj_desc_corta    = '" + entity.getDescripcionCorta() + "', \n"
                    + "       fluj_valida_monto  = '" + (entity.isValidaMonto() ? "S" : "N") + "', \n"
                    + "       fluj_comentarios   = '" + entity.getComentarios() + "', \n"
                    + "       fluj_usuario_modif = '" + usuario + "', \n"
                    + "       fluj_estatus       = '" + entity.getEstatus() + "', \n"
                    + "       fluj_fecha_modif   = SYSDATE \n"
                    + "WHERE  fluj_clave         = '" + entity.getClave() + "'";
            conexion = ConexionPool.getInstancia().getConexion();
            sentencia = conexion.prepareStatement(query);
            sentencia.executeUpdate();
        } catch (SQLException ex) {
            throw new DAOException("Error FLDU-SQL " + ex.getMessage());
        } finally {
            try {
                if (sentencia != null) {
                    sentencia.close();
                }
                if (conexion != null) {
                    conexion.close();
                }
            } catch (SQLException ex) {
                throw new DAOException("Error FLDU-SQL " + ex.getMessage());
            }
        }
    }

    protected List<Flujo> select() throws DAOException {
        Connection conexion = null;
        PreparedStatement sentencia = null;
        ResultSet resultado = null;
        List<Flujo> resultados = null;
        try {
            conexion = ConexionPool.getInstancia().getConexion();
            sentencia = conexion.prepareStatement(query);
            resultado = sentencia.executeQuery();
            resultados = new ArrayList<Flujo>();
            while (resultado.next()) {
                Flujo flujo = new Flujo();
                flujo.setClave(resultado.getString("clave"));
                flujo.setDescripcionCorta(resultado.getString("descripcion_corta") == null
                        ? ""
                        : resultado.getString("descripcion_corta"));
                flujo.setDescripcion(resultado.getString("descripcion"));
                flujo.setEstatus(resultado.getString("estatus"));
                flujo.setValidaMonto(
                        resultado.getString("monto_validado").equalsIgnoreCase("S"));
                flujo.setComentarios(resultado.getString("comentarios") == null
                        ? ""
                        : resultado.getString("comentarios"));
                flujo.setEditable(resultado.getString("editable").equalsIgnoreCase("S"));
//                flujo.setPasos(Pasos.instancia().obtener(flujo.getClave()));
                resultados.add(flujo);
            }
        } catch (SQLException ex) {
            throw new DAOException("Error FLDS-SQL " + ex.getMessage());
        } finally {
            try {
                if (resultado != null) {
                    resultado.close();
                }
                if (sentencia != null) {
                    sentencia.close();
                }
                if (conexion != null) {
                    conexion.close();
                }
            } catch (SQLException ex) {
                throw new DAOException("Error FLDS-SQL " + ex.getMessage());
            }
        }
        return resultados;
    }

    public List<Flujo> selectAll() throws DAOException {
        query = "SELECT fluj_clave        AS clave, \n"
                + "       fluj_descripcion  AS descripcion, \n"
                + "       fluj_desc_corta   AS descripcion_corta, \n"
                + "       fluj_valida_monto AS monto_validado, \n"
                + "       fluj_estatus      AS estatus, \n"
                + "       fluj_comentarios  AS comentarios, \n"
                + "       (SELECT DECODE(COUNT('X'), 0, 'S', 'N') \n"
                + "        FROM   sil_historico_flujo \n"
                + "        WHERE  hifl_fluj_clave = fluj_clave) AS editable \n"
                + "FROM sil_flujos "
                + "ORDER BY 1";
        return select();
    }

    public List<Flujo> selectWhere(String condition) throws DAOException {
        query = "SELECT fluj_clave        AS clave, \n"
                + "       fluj_descripcion  AS descripcion, \n"
                + "       fluj_desc_corta   AS descripcion_corta, \n"
                + "       fluj_valida_monto AS monto_validado, \n"
                + "       fluj_estatus      AS estatus, \n"
                + "       fluj_comentarios  AS comentarios, \n"
                + "       (SELECT DECODE(COUNT('X'),0, 'S', 'N') \n"
                + "        FROM   sil_historico_flujo \n"
                + "        WHERE  hifl_fluj_clave = fluj_clave) AS editable \n"
                + "FROM   sil_flujos \n"
                + "WHERE  " + condition
                + " ORDER BY 1";
        return select();
    }

    public String validar(String claveFlujo) throws DAOException {
        Connection conexion = null;
        PreparedStatement sentencia = null;
        ResultSet resultado = null;
        query = "SELECT sil_f_valida_flujo('" + claveFlujo + "') AS error \n"
                + "FROM   DUAL";
        String error = null;
        try {
            conexion = ConexionPool.getInstancia().getConexion();
            sentencia = conexion.prepareStatement(query);
            resultado = sentencia.executeQuery();
            while (resultado.next()) {
                error = resultado.getString("error");
            }
        } catch (SQLException ex) {
            throw new DAOException("Error FLDF-SQL " + ex.getMessage());
        } finally {
            try {
                if (resultado != null) {
                    resultado.close();
                }
                if (sentencia != null) {
                    sentencia.close();
                }
                if (conexion != null) {
                    conexion.close();
                }
            } catch (SQLException ex) {
                throw new DAOException("Error FLDF-SQL " + ex.getMessage());
            }
        }
        return error;
    }

    public String copiar(String claveFlujo, String claveNueva, String usuario) throws DAOException {
        Connection conexion = null;
        CallableStatement sentencia = null;
        String error;
        try {
            query = ("{call SIL_P_COPIA_FLUJO(?,?,?,?,?)}");
            conexion = ConexionPool.getInstancia().getConexion();
            sentencia = conexion.prepareCall(query);
            sentencia.setString(1, claveFlujo);
            sentencia.setString(2, claveNueva);
            sentencia.setString(3, usuario);
            sentencia.setString(4, "llave");
            sentencia.registerOutParameter(5, Types.VARCHAR);
            sentencia.execute();
            error = sentencia.getString(5);
        } catch (SQLException ex) {
            throw new DAOException("Error FLDP-SQL " + ex.getMessage());
        } finally {
            try {
                if (sentencia != null) {
                    sentencia.close();
                }
                if (conexion != null) {
                    conexion.close();
                }
            } catch (SQLException ex) {
                throw new DAOException("Error FLDP-SQL " + ex.getMessage());
            }
        }
        return error;
    }

    public void deleteWhere(String string) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }
}
